home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / arcadecl.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  7KB  |  314 lines

  1. /***************************************************************************
  2.  
  3.     Atari Arcade Classics hardware (prototypes)
  4.  
  5.     Note: this video hardware has some similarities to Shuuz & company
  6.     The sprite offset registers are stored to 3EFF80
  7.  
  8. ****************************************************************************/
  9.  
  10.  
  11. #include "driver.h"
  12. #include "machine/atarigen.h"
  13. #include "vidhrdw/generic.h"
  14.  
  15. #define XCHARS 43
  16. #define YCHARS 30
  17.  
  18. #define XDIM (XCHARS*8)
  19. #define YDIM (YCHARS*8)
  20.  
  21.  
  22.  
  23. /*************************************
  24.  *
  25.  *    Statics
  26.  *
  27.  *************************************/
  28.  
  29. static int *color_usage;
  30.  
  31.  
  32.  
  33. /*************************************
  34.  *
  35.  *    Prototypes
  36.  *
  37.  *************************************/
  38.  
  39. static const UINT8 *update_palette(void);
  40.  
  41. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  42. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  43.  
  44.  
  45.  
  46. /*************************************
  47.  *
  48.  *    Video system start
  49.  *
  50.  *************************************/
  51.  
  52. int arcadecl_vh_start(void)
  53. {
  54.     static struct atarigen_mo_desc mo_desc =
  55.     {
  56.         256,                 /* maximum number of MO's */
  57.         8,                   /* number of bytes per MO entry */
  58.         2,                   /* number of bytes between MO words */
  59.         0,                   /* ignore an entry if this word == 0xffff */
  60.         0, 0, 0xff,          /* link = (data[linkword] >> linkshift) & linkmask */
  61.         0                    /* render in reverse link order */
  62.     };
  63.  
  64.     static struct atarigen_pf_desc pf_desc =
  65.     {
  66.         8, 8,                /* width/height of each tile */
  67.         64, 64,                /* number of tiles in each direction */
  68.         1                    /* non-scrolling */
  69.     };
  70.  
  71.     /* allocate color usage */
  72.     color_usage = malloc(sizeof(int) * 256);
  73.     if (!color_usage)
  74.         return 1;
  75.     color_usage[0] = XDIM * YDIM;
  76.     memset(atarigen_playfieldram, 0, 0x20000);
  77.  
  78.     /* initialize the playfield */
  79.     if (atarigen_pf_init(&pf_desc))
  80.     {
  81.         free(color_usage);
  82.         return 1;
  83.     }
  84.  
  85.     /* initialize the motion objects */
  86.     if (atarigen_mo_init(&mo_desc))
  87.     {
  88.         atarigen_pf_free();
  89.         free(color_usage);
  90.         return 1;
  91.     }
  92.  
  93.     return 0;
  94. }
  95.  
  96.  
  97.  
  98. /*************************************
  99.  *
  100.  *    Video system shutdown
  101.  *
  102.  *************************************/
  103.  
  104. void arcadecl_vh_stop(void)
  105. {
  106.     /* free data */
  107.     if (color_usage)
  108.         free(color_usage);
  109.     color_usage = 0;
  110.  
  111.     atarigen_pf_free();
  112.     atarigen_mo_free();
  113. }
  114.  
  115.  
  116.  
  117. /*************************************
  118.  *
  119.  *    Playfield RAM write handler
  120.  *
  121.  *************************************/
  122.  
  123. WRITE_HANDLER( arcadecl_playfieldram_w )
  124. {
  125.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  126.     int newword = COMBINE_WORD(oldword, data);
  127.     int x, y;
  128.  
  129.     if (oldword != newword)
  130.     {
  131.         WRITE_WORD(&atarigen_playfieldram[offset], newword);
  132.  
  133.         /* track color usage */
  134.         x = offset % 512;
  135.         y = offset / 512;
  136.         if (x < XDIM && y < YDIM)
  137.         {
  138.             color_usage[(oldword >> 8) & 0xff]--;
  139.             color_usage[oldword & 0xff]--;
  140.             color_usage[(newword >> 8) & 0xff]++;
  141.             color_usage[newword & 0xff]++;
  142.         }
  143.  
  144.         /* mark scanlines dirty */
  145.         atarigen_pf_dirty[y] = 1;
  146.     }
  147. }
  148.  
  149.  
  150.  
  151. /*************************************
  152.  *
  153.  *    Periodic scanline updater
  154.  *
  155.  *************************************/
  156.  
  157. void arcadecl_scanline_update(int scanline)
  158. {
  159.     /* doesn't appear to use SLIPs */
  160.     if (scanline < YDIM)
  161.         atarigen_mo_update(atarigen_spriteram, 0, scanline);
  162. }
  163.  
  164.  
  165.  
  166. /*************************************
  167.  *
  168.  *    Main refresh
  169.  *
  170.  *************************************/
  171.  
  172. void arcadecl_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  173. {
  174.     /* remap if necessary */
  175.     if (update_palette())
  176.         memset(atarigen_pf_dirty, 1, YDIM);
  177.  
  178.     /* update the cached bitmap */
  179.     {
  180.         int x, y;
  181.  
  182.         for (y = 0; y < YDIM; y++)
  183.             if (atarigen_pf_dirty[y])
  184.             {
  185.                 int xx = 0;
  186.                 const UINT8 *src = &atarigen_playfieldram[512 * y];
  187.  
  188.                 /* regenerate the line */
  189.                 for (x = 0; x < XDIM/2; x++)
  190.                 {
  191.                     int bits = READ_WORD(src);
  192.                     src += 2;
  193.                     plot_pixel(atarigen_pf_bitmap, xx++, y, Machine->pens[bits >> 8]);
  194.                     plot_pixel(atarigen_pf_bitmap, xx++, y, Machine->pens[bits & 0xff]);
  195.                 }
  196.                 atarigen_pf_dirty[y] = 0;
  197.             }
  198.     }
  199.  
  200.     /* copy the cached bitmap */
  201.     copybitmap(bitmap, atarigen_pf_bitmap, 0, 0, 0, 0, NULL, TRANSPARENCY_NONE, 0);
  202.  
  203.     /* render the motion objects */
  204.     atarigen_mo_process(mo_render_callback, bitmap);
  205.  
  206.     /* update onscreen messages */
  207.     atarigen_update_messages();
  208. }
  209.  
  210.  
  211. /*************************************
  212.  *
  213.  *    Palette management
  214.  *
  215.  *************************************/
  216.  
  217. static const UINT8 *update_palette(void)
  218. {
  219.     UINT16 mo_map[16];
  220.     int i, j;
  221.  
  222.     /* reset color tracking */
  223.     memset(mo_map, 0, sizeof(mo_map));
  224.     palette_init_used_colors();
  225.  
  226.     /* update color usage for the mo's */
  227.     atarigen_mo_process(mo_color_callback, mo_map);
  228.  
  229.     /* rebuild the playfield palette */
  230.     for (i = 0; i < 256; i++)
  231.         if (color_usage[i])
  232.             palette_used_colors[0x000 + i] = PALETTE_COLOR_USED;
  233.  
  234.     /* rebuild the motion object palette */
  235.     for (i = 0; i < 16; i++)
  236.     {
  237.         UINT16 used = mo_map[i];
  238.         if (used)
  239.         {
  240.             palette_used_colors[0x100 + i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  241.             for (j = 1; j < 16; j++)
  242.                 if (used & (1 << j))
  243.                     palette_used_colors[0x100 + i * 16 + j] = PALETTE_COLOR_USED;
  244.         }
  245.     }
  246.  
  247.     return palette_recalc();
  248. }
  249.  
  250.  
  251.  
  252. /*************************************
  253.  *
  254.  *    Motion object palette
  255.  *
  256.  *************************************/
  257.  
  258. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  259. {
  260.     const UINT32 *usage = Machine->gfx[0]->pen_usage;
  261.     UINT16 *colormap = param;
  262.     int code = data[1] & 0x7fff;
  263.     int color = data[2] & 0x000f;
  264.     int hsize = ((data[3] >> 4) & 7) + 1;
  265.     int vsize = (data[3] & 7) + 1;
  266.     int tiles = hsize * vsize;
  267.     UINT16 temp = 0;
  268.     int i;
  269.  
  270.     for (i = 0; i < tiles; i++)
  271.         temp |= usage[code++];
  272.     colormap[color] |= temp;
  273. }
  274.  
  275.  
  276.  
  277. /*************************************
  278.  *
  279.  *    Motion object rendering
  280.  *
  281.  *************************************/
  282.  
  283. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  284. {
  285.     const struct GfxElement *gfx = Machine->gfx[0];
  286.     struct osd_bitmap *bitmap = param;
  287.     struct rectangle pf_clip;
  288.  
  289.     /* extract data from the various words */
  290.     int hflip = data[1] & 0x8000;
  291.     int code = data[1] & 0x7fff;
  292.     int xpos = (data[2] >> 7) + 4;
  293.     int color = data[2] & 0x000f;
  294. /*    int priority = (data[2] >> 3) & 1;*/
  295.     int ypos = YDIM - (data[3] >> 7);
  296.     int hsize = ((data[3] >> 4) & 7) + 1;
  297.     int vsize = (data[3] & 7) + 1;
  298.  
  299.     /* adjust for height */
  300.     ypos -= vsize * 8;
  301.  
  302.     /* adjust the final coordinates */
  303.     xpos &= 0x1ff;
  304.     ypos &= 0x1ff;
  305.     if (xpos >= XDIM) xpos -= 0x200;
  306.     if (ypos >= YDIM) ypos -= 0x200;
  307.  
  308.     /* determine the bounding box */
  309.     atarigen_mo_compute_clip_8x8(pf_clip, xpos, ypos, hsize, vsize, clip);
  310.  
  311.     /* draw the motion object */
  312.     atarigen_mo_draw_8x8(bitmap, gfx, code, color, hflip, 0, xpos, ypos, hsize, vsize, clip, TRANSPARENCY_PEN, 0);
  313. }
  314.